
//#include <iostream>
//using namespace std;

//#include <iostream>
//using namespace std;
//
//int main()
//{
//	// 以下的p、b、c、*p都是左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = 2;
//
//	// 以下几个是对上面左值的左值引用
//	int*& rp = p;
//	int& rb = b;
//	const int& rc = c;
//	int& pvalue = *p;
//	return 0;
//}


//#include <iostream>
//using namespace std;
//
//int main()
//{
//  double x = 1.1, y = 2.2;
//  // 以下几个都是常见的右值
//  10;
//  x + y;
//
//  // 以下几个都是对右值的右值引用
//  int&& rr1 = 10;
//  double&& rr2 = x + y;
//
//  // 下面是对右值的错误使用
//  // 这里编译会报错 “=”: 左操作数必须为左值
//  10 = 1;
//  x + y = 1;
//  return 0;
//}

//int main()
//{
//  int&& rr1 = 10;
//  const double&& rr2 = 10;
//
//  rr1 = 20; // 不报错 
//  rr2 = 20; // 报错
//  return 0;
//}

//int main()
//{
//  // 左值引用只能引用左值，不能引用右值。
//  int a = 10;
//  int& ra1 = a;  // 编译通过，ra为a的别名
//  int& ra2 = 10; // 编译失败，因为10是右值
//  
//  // const左值引用既可引用左值，也可引用右值。
//  const int& ra3 = 10; // 编译通过 
//  const int& ra4 = a;  // 编译通过
//  return 0;
//}

//int main()
//{
//  // 编译失败: “初始化”: 无法从“int”转换为“int &&”
//  // message : 无法将左值绑定到右值引用
//  int a = 10;
//  int&& r2 = a;
//  
//  // 右值引用可以引用move以后的左值
//  // move对左值本身不会有任何影响，相当拿用左值的值去构造一个临时对象出来
//  int&& r3 = std::move(a);
//  
//  return 0;
//}

//#include <iostream>
//using namespace std;
//
//void Func(const int& num)
//{
//  cout<<"void Func(const int& num)"<<endl;
//}
//
//void Func(int&& num)
//{
//  cout<<"void Func(int&& num)"<<endl;
//}
//
//int main()
//{
//  int x = 10;
//  int y = 20;
//  Func(x + y);
//  return 0;
//}

//// 拷贝构造
//String(const String& s)
//  :_str(nullptr)
//{
//  String tmp(s);// 深拷贝
//  this->swap(tmp);
//}
//
//// 赋值重载
//String& operator=(const String& s)
//{
//  String tmp(s);// 深拷贝
//  this->swap(tmp);
//  return *this;
//}

//#include <iostream>
//using namespace std;
//
//int main()
//{
//  // 1、构造函数
//  string s1("构造函数");
//  // 2、拷贝构造（因为传入的是左值）
//  string s2(s1);
//  // 3、移动构造（因为传入的是右值）
//  string s3(string("移动构造"));
//  return 0;
//}


#include <iostream>
using namespace std;

int main()
{
  string s1("构造函数");
  string s2("构造函数");
  // 1、深拷贝的赋值(因为=右边是左值)
  s1 = s2;
  // 2、移动赋值（因为=右边是右值）
  s1 = string("移动赋值");
}




